package com.sd365.permission.centre.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.common.aop.MyPageInfo;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.common.exception.code.BusinessErrorCode;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.core.mq.ActionType;
import com.sd365.common.util.BeanException;
import com.sd365.common.util.BeanUtil;
import com.sd365.permission.centre.dao.mapper.AdministrativeMapper;
import com.sd365.permission.centre.entity.Administrative;
import com.sd365.permission.centre.pojo.dto.AdministrativeDTO;
import com.sd365.permission.centre.pojo.query.AdministrativeQuery;
import com.sd365.permission.centre.pojo.query.IdVersionQuery;
import com.sd365.permission.centre.service.AdministrativeService;
import com.sd365.permission.centre.service.exception.UserCentreExceptionCode;
import com.sd365.permission.centre.service.util.SendMQMessageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tk.mybatis.mapper.entity.Example;

import javax.validation.Valid;
import java.util.Date;
import java.util.List;

@Service
public class AdministrativeServiceImpl extends AbstractBaseDataServiceImpl implements AdministrativeService {

    @Autowired
    private SendMQMessageUtil sendMQMessageUtil;
    private static final String TABLE_NAME = "administrative";

    @Autowired
    AdministrativeMapper administrativeMapper;

    @Autowired
    private IdGenerator idGenerator;

    @Override
    public Boolean add(@Valid AdministrativeDTO administrativeDTO) {
        Administrative administrative = BeanUtil.copy(administrativeDTO, Administrative.class);
        administrative.setId(idGenerator.snowflakeId());
        administrative.setVersion(1L);
        baseDataStuff4Add(administrative);

        Boolean flag = administrativeMapper.insert(administrative) > 0;
        if (flag) {
            sendMQMessageUtil.SendMessage(ActionType.INSERT, SendMQMessageUtil.EXCHANGE_NAME, TABLE_NAME, administrative);
        }
        return flag;
    }

    @Override
    public Boolean remove(Long id, Long version) {
        Example example = new Example(Administrative.class);
        example.createCriteria().andEqualTo("id", id).andEqualTo("version", version);
        try {
            Boolean flag = administrativeMapper.deleteByExample(example) > 0;
            if (flag) {
                Administrative administrative = new Administrative();
                administrative.setId(id);
                administrative.setVersion(version);
                sendMQMessageUtil.SendMessage(ActionType.DELETE, SendMQMessageUtil.EXCHANGE_NAME, TABLE_NAME, administrative);
            }
            return flag;
        } catch (Exception e) {
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_COMPANY_REMOVE_EXCEPTION_CODE, e);
        }
    }

    @Override
    public Boolean modify(AdministrativeDTO administrativeDTO) {
        Administrative administrative = BeanUtil.copy(administrativeDTO, Administrative.class);
        baseDataStuff4Updated(administrativeDTO);
        Example example = new Example(Administrative.class);
        example.createCriteria().andEqualTo("id", administrativeDTO.getId()).andEqualTo("version", administrativeDTO.getVersion());
        administrative.setUpdatedTime(new Date());
        Boolean flag = administrativeMapper.updateByExampleSelective(administrative, example) > 0;
        if (flag) {
            sendMQMessageUtil.SendMessage(ActionType.UPDATE, SendMQMessageUtil.EXCHANGE_NAME, TABLE_NAME, administrative);
        }
        return flag;
    }

    @Override
    public Boolean batchModify(AdministrativeDTO administrativeDTO) {
        administrativeDTO.setUpdatedTime(new Date());
        Administrative administrative = BeanUtil.copy(administrativeDTO, Administrative.class);
        baseDataStuff4Updated(administrativeDTO);
        Example example = new Example(Administrative.class);
        example.createCriteria().andEqualTo("id", administrativeDTO.getId()).andEqualTo("version", administrativeDTO.getVersion());
        return administrativeMapper.updateByExampleSelective(administrative, example) > 0;
    }

    @Override
    public List<Administrative> commonQuery(AdministrativeQuery administrativeQuery) {
        try {
            List<Administrative> administratives = administrativeMapper.commonQuery(administrativeQuery);
            Page page = (Page) administratives;
            BaseContextHolder.set("pageInfo", JSON.toJSONString(new MyPageInfo(page.getTotal(), page.getPages())));
            return administratives;
        } catch (Exception e) {
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_COMPANY_COMMONQUERY_EXCEPTION_CODE, e);
        }
    }

    @Override
    public AdministrativeDTO queryById(Long id) {
        try {
            AdministrativeDTO administrativeDTO = null;
            Administrative administrative = administrativeMapper.selectById(id);
            if (administrative != null) {
                administrativeDTO = BeanUtil.copy(administrative, AdministrativeDTO.class);
            }
            return administrativeDTO;
        } catch (BeanException ex) {
            throw new BusinessException(BusinessErrorCode.SYSTEM_BEAN_COPY_EXCEPTION, ex);
        }
    }

    @Override
    public Boolean batchDelete(List<IdVersionQuery> idVersionQueryList) {
        try {
            for (IdVersionQuery idVersionQuery : idVersionQueryList) {
                remove(idVersionQuery.getId(), idVersionQuery.getVersion());
            }
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new BusinessException(UserCentreExceptionCode.BUSINESS_COMPANY_REMOVE_BATCH_EXCEPTION_CODE, e);
        }
        return true;
    }
}
